#!/usr/bin/perl
use strict;
use warnings;
use lib ("./lib", "../lib");

package test_mapping;
use base ('Test::Class');
use Test::More;
use Test::Exception;
use DBIx::EntityRecord;

use File::Basename;
use Data::Dumper;

sub setup_loadconf : Test(setup=>7) {
    my $self = shift;
    my $confdir = dirname $0;
    {
        my $conffile = basename $0 . ".mapping";
        my $fullpath = join("/", $confdir, "conf", $conffile);
        ok( -e $fullpath );
        $self->{confpath} = $fullpath;
    }
    {
        my $classesfile = basename $0 . ".classes.pl";
        my $fullpath = join("/", $confdir, "conf", $classesfile);
        ok( -e $fullpath );
        $self->{classesfile} = $fullpath;
    }
    my $mapping;
    can_ok( 'DBIx::EntityRecord', qw/Mapping/ );
    dies_ok { $mapping = DBIx::EntityRecord->Mapping( -file => "/assumed/nonexistent/path/file.mapping" ); } 'path error';
    dies_ok { $mapping = DBIx::EntityRecord->Mapping( -file => undef ); } 'file undef';
    require_ok( $self->{classesfile} );
    lives_ok { $mapping = DBIx::EntityRecord->Mapping( -file => $self->{confpath} ); } 'after loading class';
}

sub test_mappingconf_invalids : Test(15) {
    my $self = shift;
    my $mapping;
    dies_ok { $mapping = DBIx::EntityRecord->Mapping(); } 'empty mapping';
    ok( $mapping = DBIx::EntityRecord->Mapping({ }));
    ok( $mapping = DBIx::EntityRecord->Mapping({
            entity => { } 
        }) 
    );
    dies_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "Unknown::Class::For::Sure" => undef }, 
        }) 
    } 'unknown class';
    dies_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "Unknown::Class::For::Sure" => {
                        }
            }, 
        }) 
    } 'unknown class';

    lives_ok { $mapping = DBIx::EntityRecord->Mapping( -file => $self->{confpath} ); } 'after loading class';
    ok( defined $mapping );
    isa_ok( $mapping, 'DBIx::EntityRecord::Mapping' );
    dies_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "My::Artist" => {
                        }
            }, 
        }) 
    } 'no attributes,oid,table';
    dies_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "My::Artist" => {
                            table       => "",
                        }
            }, 
        }) 
    } 'no attributes,oid,invalid table';
    dies_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "My::Artist" => {
                            table       => "sometable",
                        }
            }, 
        }) 
    } 'no attributes,oid';
    lives_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "My::Artist" => {
                            table       => "sometable",
                            attribute   => { },
                            oid         => { },
                        }
            }, 
        }) 
    } 'empty attributes,oid';
    dies_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "My::Artist" => {
                            table       => "sometable",
                            attribute   => { },
                            oid         => {
                                id  => { },
                            }
                        }
            }, 
        }) 
    } 'oid refers to non-attribute method';
    dies_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "My::Artist" => {
                            table       => "sometable",
                            attribute   => { 
                                id  => { },
                            },
                            oid         => {
                                id  => { },
                            }
                        }
            }, 
        }) 
    } 'attribute maps to undef column';
    lives_ok { $mapping = DBIx::EntityRecord->Mapping({
            entity => { "My::Artist" => {
                            table       => "sometable",
                            attribute   => { 
                                id  => { column => 'somecolumn' },
                            },
                            oid         => {
                                id  => { },
                            }
                        }
            }, 
        }) 
    } 'attribute maps to undef column';
}

sub test_mappingconf_ok : Test(4) {
    my $self = shift;
    my $mapping;
    require_ok( $self->{classesfile} );
    lives_ok { $mapping = DBIx::EntityRecord->Mapping( -file => $self->{confpath} ); } 'ok load conf';
    ok( defined $mapping );
    isa_ok( $mapping, 'DBIx::EntityRecord::Mapping' );
}


sub test_mappingconf_basic_entity : Test(11) {
    # see t/conf/10.mapping.t.mapping for the mapping file details
    my $self = shift;
    my $mapping;
    require_ok( $self->{classesfile} );
    lives_ok { $mapping = DBIx::EntityRecord->Mapping( -file => $self->{confpath} ); } 'ok load conf';
    ok( defined $mapping );
    is( $mapping->table(), undef, 'table-undef' );
    is( $mapping->table( '' ), undef, 'table-blank' );
    is( $mapping->table( 'Assumed::Non_Existent::Class' ), undef, 'table-non-existent' );
    is( $mapping->table( 'My::Artist' ), 'artist', 'table-ok' );
    # check attributes
    is( $mapping->attributes(), undef, 'attrib-undef' );
    is( $mapping->attributes(''), undef, 'attrib-blankall' );
    is( $mapping->attributes('Assumed::Non_Existent::Class'), undef, 'attrib-blankclass' );
    is_deeply( $mapping->attributes('My::Artist'), { 
            id  => { column => "artist_id" },
            name => { column => "artist_name" },
            timestamp => { column => "artist_last_update", noupdate => 1 },
        }, 
        'attrib-complete',
    );
}



__PACKAGE__->new->runtests;
